home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/view.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <dos.h>
- #include <proto/dos.h>
- #include <math.h>
- #include <exec/devices.h>
- #include <devices/audio.h>
- #include <hardware/custom.h>
-
- #define CUE 0
- #define BLK 5
-
- #define BASE 200 /* V.important constant. Used in ALL physical calcs. */
- #define BASESP 1000
- #define BASEII 4 /* For root calcs which need plenty of precision */
-
- #define TABLELENGTH (272 * BASE) /* 272 is actual length in pixels */
- #define TABLEWIDTH ((TABLELENGTH * 5 / 8)-BASE)
-
- #define X1CORNER 24
- #define Y1CORNER 62
- #define X2CORNER (X1CORNER + TABLELENGTH / BASE)
- #define Y2CORNER (Y1CORNER + TABLEWIDTH / BASE)
-
- #define BALLRADIUS (7 * BASE) /* 7 pixels */
- #define BALLDIAMETER (BALLRADIUS * 2)
- #define SCRNBALLDIAMETER (BALLDIAMETER / BASE)
- #define SEMICIRCRAD (TABLEWIDTH/6)
- #define PLACEPACK (TABLELENGTH * 5 / 8)
- #define PACKHORIZSEP (BALLDIAMETER - 2*BASE)
- #define POCKET (BALLRADIUS + 5*BASE)
- #define SCRNPOCKET (POCKET / BASE)
- #define CUETIP 10
- #define MAXCUELENGTH 80
-
- #define CLOCKWISE 1
- #define ANTICLOCKWISE 2
- #define SMALL 1
- #define LARGE 2
- #define UP 1
- #define DOWN 2
- #define NOHIT -1
- #define ON TRUE
- #define OFF FALSE
- #define HIT 3
- #define UPDATE 3
- #define ICON 2
- #define VIEW 1
- #define NOREFRESH 2
-
- #define RACKED 1
- #define BROKEN 0
- #define OPEN 2
- #define SPREAD 3
-
- #undef SINGLE
-
- enum icons { PLYR1,PLYR2,PRACTICE,DEMO,PLAY,QUIT,_BAIZE,_BALL1,_BALL2,
- SINGLE,BEST3,BEST5,UNLIMITED,STRIP,BALL10,BALL16,
- OPPONENTBASE,ICON17,ICON18,ICON19,STRIPPERBASE };
-
- enum args { GAMETYPE,GAMELENGTH,BAIZE,BALL1,BALL2,BALLCOUNT,OPPONENT,STRIPPER };
-
- #define HUMANPLYR 0
- #define COMPLYR 1
-
- #define FRICTION (BASESP / 300)
- #define SPINFRICTION 3
- #define SPEEDINC (BASESP / 16)
- #define MAXSPEED (BASESP * 4)
- #define MINSPEED (BASESP / 4)
-
- #define ESC 69
- #define RETURN 68
- #define SPACE 64
- #define LCSR 79
- #define RCSR 78
- #define UCSR 76
- #define DCSR 77
- #define F1 80
- #define F2 81
- #define F3 82
- #define F4 83
- #define F6 85
- #define F10 89
-
- #define FLASH 2
-
- #define JOYFIRE 0xbfe001
- #define LMOUSE 1
- #define RMOUSE 2
-
- #define MEMSIZE 7000
-
- void DoControl(void);
- void DrawCue(short);
- void ChangePower();
- short ChangeSpin(void);
- void DrawCross(short);
- void MoveCue(short,short);
- void DoAssigns(void);
- void SetUpTable(void);
- void DoOptions(void);
- short GetInput(void);
- char UpdateBallPos(void);
- void WaitBeam(short);
- short CheckPotted(short);
- void CheckBounce(short);
- void CheckCollision(void);
- void MakeCollision(short,short);
- void DrawBall(short,short);
- void DrawBallDirect(short,short,short);
- short FindAngle(WORD,WORD,WORD);
- void SuperImpose(struct RastPort *,short,short,struct RastPort *,
- short,short,short,short,short,short);
- void WriteMessage(short,short,short,short);
- void ScrubMessage(void);
- void PlayShot(void);
- void CheckResult(void);
- void CheckWhitePotted(void);
- short TouchingBall(short);
- void PlayComputerShot(void);
- void CopyBalls(struct ballstruct*,struct ballstruct*);
- void CopyPlayer(short,short);
- WORD QuickRoot(long);
- short GetMouse(void);
- char LoadIFF(struct IFFGraphic *,struct Screen *,char);
- char ClickDelay(short);
- void CueJumpAnim(void);
- void CheckAngle(short *);
- UWORD Rand(UWORD);
- short AudioOpenIt(void);
- long MyRead(struct FileHandle *,long *,long);
- char OpenIt(void);
- void CloseIt(void);
-
- APTR GetDeviceBlock(ULONG);
- void FreeDeviceBlock(struct IOAudio *,BYTE);
- void Audio_PerVol(struct IOAudio *,UWORD,UWORD);
- void Audio_Write(struct IOAudio *,UBYTE *,UWORD);
- void PlaySound(struct audioinfostruct *,short);
-
- /******************* Graphics defines ******************/
- struct NewScreen ns;
- struct NewWindow nw;
-
- /* Extra padding for use with tempmask. Must set ballmask to point to */
- /* first 'real' byte (8) at start of program */
-
- USHORT chip crossmask[5];
- USHORT chip mask[37];
- USHORT chip mask2[10];
- USHORT chip hybridmask[13];
- USHORT chip hybridmask2[10];
- USHORT chip miniball[8];
-
- USHORT *ballmask = &mask[12];
- USHORT *ballmask2 = mask2;
- USHORT chip tempmask[256];
-
- USHORT chip buffer[20];
-
- /********************* System defines ************************/
- struct Screen *s,*s2;
- struct Window *w,*w2;
- struct RastPort *rp,*rp2,bufrp;
- struct BitMap *bm,*bm2,bufbm;
- struct ViewPort *vp;
- struct ColorMap *cm;
- struct IntuiMessage *msg;
- struct FileHandle *fh;
- struct Preferences prefs;
-
- UWORD *colorpalette;
-
- char *bp0,*bp1,*bp2,*bp3,*bp4;
-
- long oldkeyspeed,oldkeydelay;
-
- /******************* Audio Defines ******************/
-
- #define SAMPLES 8
- #define AM2 106 /* Audio Master II info size */
- #define BUFWAVELEN 100
-
- enum sound { COLLIDE,STRIKE,BOUNCE,POTTED,CHEER,LONGCHEER,CHANT,CRASH };
-
- #define AUDIO_LEN (sizeof(struct IOAudio))
- #define PRECIDENCE 127
- #define CLOSE_DEVICE 1
-
- struct IOAudio *audio[4];
- char Channel_Map[] = { 1,2,4,8 },*bufwave;
-
- struct audioinfostruct
- {
- struct IOAudio *audio;
- char *wave,bufstate,channel,flag;
- long wavelen;
- short volume,period;
- char filename[30];
- };
-
- #define BUFFER 0
- #define RESET 1
-
- struct audioinfostruct audioinfo[SAMPLES];
-
- /********************* Gameplay defines **********************/
- UWORD rgb[32];
- UWORD rgb2[32];
-
- enum col {
- _back,_leather,_dkleather,_ltbaize,_dkbaize,_dkwalnut,_walnut,_ltwalnut,
- _baize,_yellow,_red,_ltbaize2,_white,_highyel,_highred,_ltbaize3,
- _cross,_ptr17,_ptr18,_ptr19,_cuecol,_ltcuecol,_22,_23,
- _black,_text1,_text2 };
-
- enum balltype { white,black,yellow,red, anyball,baize };
- char ballpalette[] = { _white,_black,_yellow,_red, 0,_baize };
-
- char ball9colour[],ball15colour[];
-
- char ballplanes[] = { 4,16,1,2, 0,23 };
-
- struct ballstruct
- {
- enum balltype colour;
- char potted,justpotted,hasmoved,lasthit,olddx,olddy;
- USHORT x,y;
- short speed,angle,scrnx,scrny,oldscrnx,oldscrny;
- };
- struct ballstruct ball[16],tempball[16];
-
- struct playerstruct
- {
- enum balltype colour;
- char goes,wins;
- char nametag;
- short maxpower;
- char cuepulls,skill;
- };
- struct playerstruct player[8];
-
- struct pixelsavestruct
- {
- char col;
- short x,y;
- };
- struct pixelsavestruct pixelsave[32];
-
- struct blitdatstruct
- {
- short x,y,dx,dy;
- };
- struct blitdatstruct blitdat,blitdat2;
-
- short *memblock, *quicksin, *quickcos;
- char *quickarcsin;
-
- WORD cueangle=270,cuespeed=MINSPEED,powerdirn=UP,
- spinx,spiny,swerve,swervetotal;
-
- USHORT seed; /* random element */
-
- short gametype,gamelength,stripper,opponent,
- cueline,cloth,firsthit,turn,dotspacing=8,newbreak,cheer,
- comp1,comp2,foul,endofgame,quitgame,winner,matches,coin,balls,
- packstate,plyrbreak;
-
- USHORT pocketx[6];
- USHORT pockety[6];
-
- char angleused[360];
-
- char joydelay;
-
- extern struct Custom far custom;
-
- /********* Loader stuff *************/
-
- extern struct IFFGraphic /* defined in load.c */
- {
- char FileName[30]; /* Name of IFF file */
- BYTE ReqDepth; /* How many bitplanes wish to be Displayed */
- USHORT *RGB; /* RGB colour values, filled by LoadIFF */
- short Width; /* Width of graphic, filled by LoadIFF */
- short Height; /* Height of graphic, filled by LoadIFF */
- BYTE Depth; /* Depth of graphic, filled by LoadIFF */
- };
- extern char arg[8];
- struct IFFGraphic tableIFF = { "fnpool:table.img",5,NULL };
-
- UWORD RGBbaize[20];
- UWORD RGBball[7];
- UWORD RGBroom[16];
-
- /********** Strip stuff *****************/
-
- struct IFFGraphic roomIFF;
- struct IFFGraphic stripIFF[4];
-
- struct stripstruct
- { short imgx1[4],imgy1[4],imgdx[4],imgdy[4],imgx2[4],imgy2[4],
- textfiletag[5],textx[5],texty[5],textdx[5],textdy[5]; };
-
- /******* Message stuff *****************/
-
- #define NEW 0
- #define FOLLOW 1
-
- short cursor;
-
- enum msg { MSG_PLACECUEBALL,MSG_FOUL,MSG_WINS,MSG_MICHAEL,MSG_JOSH,
- MSG_CLAIRE,MSG_SALLY,MSG_PLAYER1,MSG_PLAYER2,MSG_QUITTING,
- MSG_VS,MSG_GAME,MSG_OF,MSG_0,MSG_1,MSG_2,MSG_3,MSG_4,MSG_5,
- MSG_GOODSHOT,MSG_SHOTCANCELLED,MSG_BADLUCK,MSG_WELLDONE,
- MSG_QUITGAME,MSG_ISTHECHAMP,MSG_OOOPS };
-
- struct messagestruct { short x1,y1,x2,y2; };
- struct messagestruct message[];
-
- /************************/
- char OpenIt()
- {
- short i;
-
- if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) return(0);
- if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0))) return(0);
-
- if (!(s2 = OpenScreen(&ns))) return(0);
- if (!(s = OpenScreen(&ns))) return(0);
- nw.Screen = s;
- if (!(w = OpenWindow(&nw))) return(0);
- nw.Screen = s2;
- if (!(w2 = OpenWindow(&nw))) return(0);
- if (!AudioOpenIt()) return(0);
- if (!(memblock = AllocMem(MEMSIZE,MEMF_PUBLIC))) return(0);
-
- cm = GetColorMap(32);
- s->ViewPort.ColorMap = cm;
- s2->ViewPort.ColorMap = GetColorMap(32);
- rp = &s->RastPort; bm = &s->BitMap;
- rp2 = &s2->RastPort; bm2 = &s2->BitMap;
- colorpalette = (UWORD *)cm->ColorTable;
- bp0 = s->BitMap.Planes[0]; bp1 = s->BitMap.Planes[1];
- bp2 = s->BitMap.Planes[2]; bp3 = s->BitMap.Planes[3];
- bp4 = s->BitMap.Planes[4];
- for (i=0; i<32; i++) colorpalette[i] = 0;
- MakeScreen(s); RethinkDisplay();
-
- InitBitMap(&bufbm,5,320,256);
- for (i=0; i<5; i++)
- if (!(bufbm.Planes[i] = AllocRaster(320,256))) return(0);
-
- InitRastPort(&bufrp); bufrp.BitMap = &bufbm;
- bufrp.Mask = 31;
-
- while (!(fh = (struct FileHandle *) Open("FNPGRAPHICS:message.img",MODE_OLDFILE)));
-
- Seek((BPTR)fh,8,OFFSET_BEGINNING);
- MyRead(fh,bufbm.Planes[0]+(175*40),(40*78));
- MyRead(fh,bufbm.Planes[1]+(175*40),(40*78));
- Close((BPTR)fh);
-
- GetPrefs(&prefs,sizeof(struct Preferences));
- prefs.KeyRptSpeed.tv_secs = 0;
- oldkeyspeed = prefs.KeyRptSpeed.tv_micro;
- prefs.KeyRptSpeed.tv_micro = 10000;
- prefs.KeyRptDelay.tv_secs = 0;
- prefs.KeyRptDelay.tv_micro = 300000;
- oldkeydelay = prefs.KeyRptDelay.tv_micro;
- prefs.PointerTicks = 1;
- SetPrefs(&prefs,sizeof(struct Preferences),TRUE);
- return(1);
- }
- /**********************/
- void WriteMessage(i,x,y,flag)
- short i,x,y,flag;
- {
- short dx = 1 + message[i].x2-message[i].x1;
- short dy = 1 + message[i].y2-message[i].y1;
-
- if (flag==NEW) { ScrubMessage(); cursor=5; }
-
- SetWrMsk(rp,31); SetAPen(rp,_black);
- RectFill(rp,x+cursor,7+y,x+cursor+dx,7+y+dy);
-
- BltBitMap(&bufbm,message[i].x1,175 + message[i].y1,bm,x+cursor,7+y,
- dx,dy,0xc0,3,buffer);
-
- cursor += 10 + dx + x;
- }
- /***********************/
- void ScrubMessage()
- {
- SetWrMsk(rp,31); SetAPen(rp,_black);
- RectFill(rp,10,12,145,30);
- }
- /***********************/
- void PlayShot()
- {
- short i,volume;
-
- ball[CUE].angle = cueangle+180;
- CheckAngle(&ball[CUE].angle);
- ball[CUE].speed = cuespeed;
- ball[CUE].lasthit = NOHIT;
- firsthit=0; /* Which ball is hit first */
- for (i=0; i<balls; i++) ball[i].justpotted=FALSE;
- DrawCue(OFF); DrawCue(HIT);
-
- if ((volume = 16 + (ball[CUE].speed<<6)/MAXSPEED) > 64) volume = 64;
- PlaySound(&audioinfo[STRIKE],volume);
-
- while(UpdateBallPos()) CheckCollision();
-
- for (i=0; i<balls; i++) if (!ball[i].potted) DrawBall(i,ON);
-
- spinx = 0; spiny = 0; swerve = 0; swervetotal = 0;
- if (gametype==PRACTICE)
- {
- for (i=1; i<balls; i++) if (!ball[i].potted) break;
- if (i==balls) /* No balls left on table */ endofgame=TRUE;
- }
- else
- {
- CheckResult();
- if (player[turn].colour==black && !endofgame && cheer)
- PlaySound(&audioinfo[CHANT],64);
- }
- if (packstate!=RACKED) newbreak=FALSE;
-
- if (packstate==OPEN)
- {
- for (i=1; i<balls; i++) if (!ball[i].hasmoved) break;
- if (i==balls) packstate=SPREAD;
- }
- cuespeed=MINSPEED;
- if (endofgame) { DrawCue(ON); return; }
- CheckWhitePotted();
- WriteMessage(player[turn].nametag,5,5,NEW);
- Delay(20); DrawCue(ON);
- }
- /**********************/
- void CheckWhitePotted()
- {
- short returnhit=FALSE,angle,hyp;
-
- if (ball[CUE].potted)
- {
- WriteMessage(MSG_PLACECUEBALL,5,5,NEW); Delay(50);
-
- ball[CUE].potted = FALSE;
- ball[CUE].x = (TABLELENGTH/4);
- ball[CUE].y = (TABLEWIDTH/2 - BASE*3) + Rand(BASE*6);
- ball[CUE].speed = 0;
-
- while(TouchingBall(CUE)!=NOHIT)
- {
- /* White ball has been placed over another ball! */
-
- angle = Rand(180);
- hyp = Rand(SEMICIRCRAD);
-
- ball[CUE].x = TABLELENGTH/4 -
- quicksin[angle]*hyp/BASE;
- ball[CUE].y = TABLEWIDTH/2 +
- quickcos[angle]*hyp/BASE;
- }
- ball[CUE].scrnx = ball[CUE].x/BASE;
- ball[CUE].scrny = ball[CUE].y/BASE;
-
- DrawBall(CUE,ON);
- if (!(gametype == DEMO || (gametype==PLYR1 && turn==COMPLYR)))
- while(!returnhit)
- {
- short dx,dy,opp,adj;
-
- dx=0; dy=0;
- switch (GetInput())
- {
- case 76: dy=BASE; break;
- case 77: dy=-BASE; break;
- case 78: dx=BASE; break;
- case 79: dx=-BASE; break;
- case 68: returnhit = TRUE; break;
- }
- WaitTOF(); DrawBall(CUE,OFF);
-
- opp = ((ball[CUE].x+=dx) - TABLELENGTH/4)/BASE;
- adj = ((ball[CUE].y+=dy) - TABLEWIDTH/2)/BASE;
- ball[CUE].scrnx = ball[CUE].x/BASE;
- ball[CUE].scrny = ball[CUE].y/BASE;
-
- if (opp > 0 ||
- QuickRoot(opp*opp + adj*adj) > SEMICIRCRAD/BASE ||
- TouchingBall(CUE)!=NOHIT)
- { ball[CUE].x-=dx; ball[CUE].y-=dy; }
- DrawBall(CUE,ON);
- }
- ball[CUE].oldscrnx = ball[CUE].scrnx;
- ball[CUE].oldscrny = ball[CUE].scrny;
- }
- }
- /**********************/
- void CopyPlayer(from,to)
- short from,to;
- {
- player[to].nametag = player[from].nametag;
- player[to].maxpower = player[from].maxpower;
- player[to].cuepulls = player[from].cuepulls;
- player[to].skill = player[from].skill;
- player[to].wins = player[from].wins;
- }
- /**********************/
- void SuperImpose(srcrp,x0,y0,destrp,x1,y1,dx,dy,transp,offset)
- short x0,y0,dx,dy,x1,y1,transp,offset;
- struct RastPort *srcrp,*destrp;
- {
- register short x,y,pixel;
-
- for (y=0; y < dy; y++)
- for (x=0; x < dx; x++)
- if ((pixel = ReadPixel(srcrp,x0+x,y0+y)) != transp)
- { SetAPen(destrp,offset+pixel); WritePixel(destrp,x1+x,y1+y); }
- }
- /**********************/
- short ChangeSpin()
- {
- short input,retnval=TRUE,new=FALSE,spinx2=spinx,spiny2=spiny;
-
- rp->Mask = 31; DrawCross(ON);
-
- do
- {
- input = GetInput();
- switch(input)
- {
- case UCSR: if (spiny < 400) { spiny2=spiny+100; new=1; }
- break;
- case DCSR: if (spiny > -800) { spiny2=spiny-100; new=1; }
- break;
- case RCSR: if (spinx < 600) { spinx2=spinx+100; new=2; }
- break;
- case LCSR: if (spinx > -600) { spinx2=spinx-100; new=2; }
- break;
- case ESC: spinx2=0; spiny2=0; new=1; retnval=FALSE; break;
- }
- switch (new)
- {
- case 2:
- {
- short tempx = spinx,tempy = spiny;
-
- DrawCue(OFF); spinx=spinx2; spiny=spiny2; DrawCue(ON);
- spinx = tempx; spiny = tempy;
- }
- case 1:
- DrawCross(OFF); spinx=spinx2; spiny=spiny2;
- DrawCross(ON); new=FALSE; break;
- }
-
- } while (input!=RETURN && input!=ESC);
-
- DrawCross(OFF);
- swerve = abs(spiny) * spinx / 4800;
- return retnval;
- }
- /**********************/
- void DrawCross(status)
- short status;
- {
- blitdat2.x = 157+spinx/100;
- blitdat2.y = 14-spiny/100;
- blitdat2.dx = 5; blitdat2.dy = 5;
-
- if (status==OFF)
- {
- WaitBeam(40);
- BltBitMap(&bufbm,0,85,bm,blitdat2.x,blitdat2.y,
- blitdat2.dx,blitdat2.dy,0xc0,31,buffer);
- }
- else
- {
- SetAPen(rp,_cross);
- BltBitMap(bm,blitdat2.x,blitdat2.y,&bufbm,
- 0,85,blitdat2.dx,blitdat2.dy,0xc0,31,buffer);
-
- BltPattern(rp,crossmask,
- 157+spinx/100,14-spiny/100,
- 161+spinx/100,18-spiny/100,2);
- }
- }
- /**********************/
- void ChangePower()
- {
- short offset;
-
- if (powerdirn==DOWN)
- {
- if ((cuespeed-=(SPEEDINC/2)) < MINSPEED)
- { powerdirn=UP; cuespeed=MINSPEED; }
- }
- else if ((cuespeed+=SPEEDINC) > MAXSPEED)
- { powerdirn=DOWN; cuespeed=MAXSPEED; }
-
- offset = (cuespeed*16)/BASESP;
-
- rp->Mask = 31;
- WaitBeam(21);
- SetAPen(rp,_back); RectFill(rp,201+offset,18,265,21);
- SetAPen(rp,_white); RectFill(rp,199,18,200+offset,21);
- }
- /**********************/
- void WaitBeam(y)
- short y;
- {
- short vert;
- while(1)
- {
- vert = VBeamPos();
- if (vert > y+40 && vert < y+70) break;
- }
- }
- /**********************/
- void MoveCue(dirn,increment)
- short dirn,increment;
- {
- DrawCue(OFF);
-
- if (dirn==CLOCKWISE) cueangle += (increment==SMALL)? 1:10;
- else cueangle -= (increment==SMALL)? 1:10;
- CheckAngle(&cueangle);
- DrawCue(ON);
- }
- /**********************/
- void DoAssigns()
- {
- /* short i; */
-
- quicksin = memblock;
- quickcos = quicksin+361;
- quickarcsin = quickcos+361;
-
- /*
- for (i=0; i<361; i++)
- {
- quicksin[i] = sin((double)i * PI / 180.0) * (double)BASE;
- quickcos[i] = cos((double)i * PI / 180.0) * (double)BASE;
- }
- for (i=0; i<5001; i++)
- quickarcsin[i] = asin((double)i / 5000.0) * 180.0 / PI;
- */
- while (!(fh = (struct FileHandle *)Open("FNP:trig.dat",MODE_OLDFILE)));
-
- Read((BPTR)fh,quicksin,361*2);
- Read((BPTR)fh,quickcos,361*2);
- Read((BPTR)fh,quickarcsin,5001);
- Close((BPTR)fh);
- }
- /**********************/
- short GetInput()
- {
- short code = NULL,code2;
- ULONG joy = (ULONG)custom.joy1dat; /* joystick info */
-
- if (joydelay==1) { Delay(10); joydelay=2; }
- else if (!(gametype==PLYR2 && turn == 1))
- {
- if ((long)(joy & 768) == 512L) code = LCSR; /* Up-left */
- else if ((long)(joy & 3) == 2L) code = RCSR; /* Down-right */
- else if ((long)(joy & 3) == 3L) code = RCSR;
- else if ((long)(joy & 768L) == 768L) code = LCSR;
- else if ((long)(joy & 768) == 256L) code = UCSR;
- else if ((long)(joy & 3) == 1L) code = DCSR;
- else joydelay = 0;
-
- if (!joydelay && code) joydelay=1;
-
- while (!(*(char *)JOYFIRE & 0x80)) code = RETURN;
- if (code==RETURN) Delay(20); /* Joystick fire */
- }
-
- if (!(msg = (struct IntuiMessage *)GetMsg(w->UserPort)))
- return code;
- do
- {
- code2 = msg->Code;
- ReplyMsg((struct Message *)msg);
-
- } while((msg = (struct IntuiMessage *)GetMsg(w->UserPort)) &&
- code2!=ESC);
-
- if (gametype==PLYR2 && turn == 0)
- {
- switch (code2)
- {
- case UCSR:
- case DCSR:
- case LCSR:
- case RCSR:
- case RETURN: return code;
- }
- }
- return code2;
- }
- /**********************/
- char UpdateBallPos()
- {
- short i,j,x1,y1,x2,y2,dx,dy;
- char ballsmoving = FALSE;
-
- for(i=0; i<balls; i++) /* Update ball position */
- if (!ball[i].potted && ball[i].speed > 0)
- {
- ballsmoving=TRUE; ball[i].hasmoved=TRUE;
- ball[i].x += ball[i].speed * quicksin[ball[i].angle] / BASESP;
- ball[i].y += ball[i].speed * quickcos[ball[i].angle] / BASESP;
-
- if ((ball[i].scrnx = ball[i].x/BASE) - ball[i].oldscrnx |
- (ball[i].scrny = ball[i].y/BASE) - ball[i].oldscrny)
- {
- if (CheckPotted(i))
- { ball[i].potted = TRUE; ball[i].justpotted = TRUE; }
- else CheckBounce(i);
-
- if (ball[i].potted)
- {
- ball[i].scrnx = ball[i].oldscrnx;
- ball[i].scrny = ball[i].oldscrny;
- DrawBall(i,OFF);
- }
- else
- {
- USHORT *tmask = tempmask+(i<<4);
-
- x1 = (X1CORNER-8) + ball[i].oldscrnx;
- y1 = (Y2CORNER-7) - ball[i].oldscrny;
- x2 = (X1CORNER-8) + ball[i].scrnx;
- y2 = (Y2CORNER-7) - ball[i].scrny;
- dx = x2-x1; dy = y2-y1;
-
- if (dx != ball[i].olddx || dy != ball[i].olddy)
- {
- register USHORT *quickmask = ballmask;
-
- if (dx >= 0) for (j=0; j<13; j++)
- tmask[j] = quickmask[j] ^
- (quickmask[j] & (*(quickmask+j-dy) >> dx));
-
- else for (j=0; j<13; j++)
- tmask[j] = quickmask[j] ^
- (quickmask[j] & (*(quickmask+j-dy) << -dx));
-
- ball[i].olddx = dx; ball[i].olddy = dy;
- }
-
- if (ball[i].colour != white)
- {
- register char *ptr = bp2 + (y1+3)*40 + ((x1+7)>>3);
- register short data = 128 >> ((x1+7) % 8);
-
- ptr[0] &= ~data; ptr[80] &= ~data;
- if (data==1)
- { ptr[40] &= 252; ptr[41] &= 127; }
- else if (data==128)
- { ptr[40] &= 63; ptr[39] &= 254; }
- else ptr[40] &= ~(data + (data>>1) + (data<<1));
- }
- DrawBallDirect(ball[i].colour,x2,y2);
- SetAPen(rp,_baize);
- rp->Mask = ballplanes[ball[i].colour];
- BltPattern(rp,tmask,x1,y1,x1+15,y1+12,2);
-
- ball[i].oldscrnx = ball[i].scrnx;
- ball[i].oldscrny = ball[i].scrny;
- }
- }
- if (balls==10) ball[i].speed-=(FRICTION/2);
- else ball[i].speed-=FRICTION;
- if (ball[i].speed < 0) ball[i].speed = 0;
- }
- spinx -= (spinx > 0)? SPINFRICTION:-SPINFRICTION;
- spiny -= (spiny > 0)? SPINFRICTION:-SPINFRICTION;
- if ((swervetotal+=abs(swerve)) > 99)
- {
- ball[CUE].angle += (swerve > 0)? 1:-1;
- CheckAngle(&ball[CUE].angle);
- swervetotal-=100;
- }
- swerve -= (swerve > 0)? 1:-1;
- return ballsmoving;
- }
- /**********************/
- short CheckPotted(i)
- short i;
- {
- BOOL potted = FALSE;
- short volume;
- register USHORT x = ball[i].x, y = ball[i].y;
-
- if (ball[i].potted) return(FALSE);
-
- if (x > (TABLELENGTH-BALLRADIUS) &&
- (y < POCKET || y > (TABLEWIDTH-POCKET)))
- potted = TRUE;
-
- else if (x < BALLRADIUS && (y < POCKET || y > (TABLEWIDTH-POCKET)))
- potted = TRUE;
-
- else if (y < BALLRADIUS &&
- (x < POCKET ||
- (x > (TABLELENGTH/2 - POCKET/2) &&
- x < (TABLELENGTH/2 + POCKET/2)) ||
- x > (TABLELENGTH-POCKET)))
- potted = TRUE;
-
- else if (y > (TABLEWIDTH-BALLRADIUS) &&
- (x < POCKET ||
- (x > (TABLELENGTH/2 - POCKET/2) &&
- x < (TABLELENGTH/2 + POCKET/2)) ||
- x > (TABLELENGTH-POCKET)))
- potted = TRUE;
-
- if (potted)
- {
- if ((volume = 16 + (ball[i].speed<<6)/MAXSPEED) > 64) volume = 64;
- PlaySound(&audioinfo[POTTED],volume);
- if (ball[i].speed > (MAXSPEED*5/8) && !(Rand(4)))
- {
- ball[i].angle+=180; CheckAngle(&ball[i].angle);
- ball[i].x += ball[i].speed * quicksin[ball[i].angle] / BASESP;
- ball[i].y += ball[i].speed * quickcos[ball[i].angle] / BASESP;
- ball[i].scrnx = ball[i].x/BASE; ball[i].scrny = ball[i].y/BASE;
- ball[i].speed >>= 2; ball[i].lasthit=NOHIT; potted=FALSE;
- }
- }
- return(potted);
- }
- /**********************/
- void CheckBounce(i)
- short i;
- {
- short bounce=FALSE,volume;
- register USHORT x = ball[i].x, y = ball[i].y;
- register short angle = ball[i].angle;
-
- if (ball[i].potted) return;
-
- if (x < BALLRADIUS && angle > 180)
- { angle=360-ball[i].angle; bounce=TRUE; }
-
- else if (x > (TABLELENGTH-BALLRADIUS) && angle < 180)
- { angle=360-ball[i].angle; bounce=TRUE; }
-
- else if (y < BALLRADIUS && angle < 270 && angle > 90)
- {
- if (angle <= 180) angle=180-ball[i].angle;
- else angle=540-ball[i].angle; bounce=TRUE;
- }
- else if (y > (TABLEWIDTH-BALLRADIUS) && (angle > 270 || angle < 90))
- {
- if (angle <= 180) angle=180-ball[i].angle;
- else angle=540-ball[i].angle; bounce=TRUE;
- }
- if (bounce)
- {
- if ((volume = 16 + (ball[i].speed<<6)/MAXSPEED) > 64) volume = 64;
- PlaySound(&audioinfo[BOUNCE],volume);
- if (ball[CUE].speed > (MAXSPEED*3/4) && spiny < -600 && !(Rand(3)))
- CueJumpAnim();
-
- ball[i].angle = angle;
- ball[i].x += ball[i].speed * quicksin[ball[i].angle] / BASESP;
- ball[i].y += ball[i].speed * quickcos[ball[i].angle] / BASESP;
- ball[i].scrnx = ball[i].x/BASE; ball[i].scrny = ball[i].y/BASE;
- if (ball[i].scrnx < (BALLRADIUS/BASE)) ball[i].scrnx = (BALLRADIUS/BASE);
- else if (ball[i].scrnx > ((TABLELENGTH-BALLRADIUS)/BASE))
- ball[i].scrnx = ((TABLELENGTH-BALLRADIUS)/BASE);
- if (ball[i].scrny < (BALLRADIUS/BASE)) ball[i].scrny = (BALLRADIUS/BASE);
- else if (ball[i].scrny > ((TABLEWIDTH-BALLRADIUS)/BASE))
- ball[i].scrny = ((TABLEWIDTH-BALLRADIUS)/BASE);
- ball[i].speed = ((ball[i].speed << 3) - ball[i].speed) >> 3;
- ball[i].lasthit = NOHIT;
- if (i==CUE)
- {
- ball[CUE].angle -= spinx / 25;
- spinx = 0; spiny = 0; swerve = 0;
- CheckAngle(&ball[CUE].angle);
- }
- if (packstate==BROKEN) packstate=OPEN; /* can now hear all collisions */
- }
- }
- /**********************/
- short GetMouse()
- {
- short status=0;
-
- UBYTE *leftmouse = (UBYTE *)0xbfe001;
- UWORD *rightmouse = (UWORD *)0xdff016;
-
- if (!(*leftmouse & 0x40)) status |= LMOUSE;
- if ((*rightmouse & 0x0400) != 0x0400) status |= RMOUSE;
- return status;
- }
- /****************/
- void SetUpTable()
- {
- short i,j,k,offset,oldoffset=0;
-
- for (i=0; i<balls; i++) if (!ball[i].potted && ball[i].x)
- {
- ball[i].x = ball[i].oldscrnx*BASE;
- ball[i].y = ball[i].oldscrny*BASE;
- DrawBall(i,OFF);
- }
- ball[CUE].x = (TABLELENGTH/4);
- ball[CUE].y = (TABLEWIDTH/2 - BASE*3) + Rand(BASE*6);
-
- for (i=0,k=1; i<5; i++)
- for (j=0; j<=i; j++,k++)
- {
- ball[k].x = (PLACEPACK-BASE) + PACKHORIZSEP*i;
- ball[k].y = (TABLEWIDTH / 2) + (BALLDIAMETER *j) -
- (BALLDIAMETER * i / 2) - BASE;
- ball[k].x += Rand((BASE/2));
- ball[k].y += Rand((BASE/2));
- }
-
- if (balls==10)
- {
- ball[7].y+=BALLDIAMETER; ball[8].y+=BALLDIAMETER;
- ball[9].x+=PACKHORIZSEP; ball[9].y-=(BALLDIAMETER/2);
- for (i=0; i<10; i++) ball[i].colour = ball9colour[i];
- }
- else for (i=0; i<16; i++) ball[i].colour = ball15colour[i];
-
- BltBitMap(&bufbm,200,0,bm,182,107,71,79,0xc0,31,buffer);
- if (gametype!=PRACTICE && cheer) PlaySound(&audioinfo[CHEER],64);
-
- for (i=0; i<balls; i++)
- {
- ball[i].potted = FALSE; ball[i].speed = 0;
- ball[i].lasthit = NOHIT;
- ball[i].hasmoved = 0;
- ball[i].scrnx = ball[i].x/BASE;
- ball[i].scrny = ball[i].y/BASE;
- ball[i].oldscrnx = ball[i].scrnx;
- ball[i].oldscrny = ball[i].scrny;
- ball[i].olddx = -99; ball[i].olddy = -99;
- DrawBall(i,ON);
- }
- if (balls==16) for (j=0,k=25; j<5; j++,k-=5)
- {
- for (i=0; i<=360; i+=30)
- {
- offset = quicksin[i]*k/BASE;
- WaitBeam(185);
- BltBitMap(bm,(182-15)-oldoffset,107,
- bm,(182-15)-offset,107,(71+30),79,0xc0,31,buffer);
- if (i==90 || i==270) PlaySound(&audioinfo[COLLIDE],64);
- oldoffset = offset;
- }
- }
- Delay(30);
- BltBitMap(bm,100,107,bm,182,107,71,79,0xc0,31,buffer);
- for (i=1; i<balls; i++) DrawBall(i,ON);
-
- if (coin==-1) coin = Rand(2);
- coin = 1-coin; turn = coin;
- if (balls==16)
- { player[0].colour = anyball; player[1].colour = anyball; }
- else { player[0].colour = red; player[1].colour = red; }
-
- player[turn].goes = 1;
-
- if (gametype!=PRACTICE) DrawBall(player[turn].colour,ICON);
- cueangle = 270; DrawCue(ON);
- packstate=RACKED; plyrbreak=0; newbreak=TRUE;
- }
- /**********************/
- void CheckBallDrag()
- {
- short i,x,y,button;
-
- if (button = GetMouse())
- {
- x = s->MouseX; y = s->MouseY;
-
- for (i=0; i<balls; i++)
- {
- if (!ball[i].potted &&
- x > ball[i].scrnx+(X1CORNER-7) &&
- x < ball[i].scrnx+(X1CORNER+8) &&
- y > (Y2CORNER-8)-ball[i].scrny &&
- y < (Y2CORNER+8)-ball[i].scrny &&
- ReadPixel(rp,x,y) != _baize)
- {
- DrawCue(OFF);
- if (button==RMOUSE && i!=CUE)
- {
- DrawBall(i,OFF);
- ball[i].potted = TRUE;
- PlaySound(&audioinfo[POTTED],64);
- }
- else if (button==LMOUSE)
- {
- PlaySound(&audioinfo[COLLIDE],64);
- while (GetMouse() == LMOUSE)
- {
- short oldx,oldy;
-
- x = s->MouseX; y = s->MouseY;
- if (x < (X1CORNER+7)) x = (X1CORNER+7);
- if (x > (X2CORNER-8)) x = (X2CORNER-8);
- if (y < (Y1CORNER+8)) y = (Y1CORNER+8);
- if (y > (Y2CORNER-7)) y = (Y2CORNER-7);
- {
- oldx = ball[i].x; oldy = ball[i].y;
- ball[i].x = (x-X1CORNER)*BASE;
- ball[i].y = (Y2CORNER-y)*BASE;
- if (TouchingBall(i)==NOHIT)
- {
- WaitBeam(y+7); DrawBall(i,OFF);
- ball[i].scrnx = ball[i].x/BASE;
- ball[i].scrny = ball[i].y/BASE;
- DrawBall(i,ON);
- }
- else { ball[i].x = oldx; ball[i].y = oldy; }
- }
- }
- }
- ball[i].oldscrnx = ball[i].scrnx;
- ball[i].oldscrny = ball[i].scrny;
- DrawCue(ON); while (GetMouse());
- }
- }
- if (button==(LMOUSE|RMOUSE))
- {
- for (i=1; i<balls; i++)
- if (ball[i].potted &&
- x > (X1CORNER+6) && x < (X2CORNER-8) &&
- y > (Y1CORNER+8) && y < (Y2CORNER-6))
- {
- ball[i].potted = FALSE;
- ball[i].x = (x-X1CORNER)*BASE;
- ball[i].y = (Y2CORNER-y)*BASE;
- if (TouchingBall(i)==NOHIT)
- {
- DrawCue(OFF);
- ball[i].scrnx = ball[i].x/BASE;
- ball[i].scrny = ball[i].y/BASE;
- ball[i].oldscrnx = ball[i].scrnx;
- ball[i].oldscrny = ball[i].scrny;
- ball[i].speed = 0;
- WaitBeam(y+7); DrawBall(i,ON);
- PlaySound(&audioinfo[COLLIDE],64);
- DrawCue(ON); break;
- }
- else ball[i].potted = TRUE;
- }
- while (GetMouse());
- }
- }
- }
-
- /**********************/
- void CheckCollision()
- {
- char i;
- BOOL collision;
-
- for(i=0; i<balls; i++) /* Check for collisions */
- {
- register short x1 = ball[i].scrnx + SCRNBALLDIAMETER;
- register short y1 = ball[i].scrny + SCRNBALLDIAMETER;
- register short x2 = x1 - (SCRNBALLDIAMETER*2);
- register short y2 = y1 - (SCRNBALLDIAMETER*2);
- register char j;
-
- for(j=i+1; j<balls; j++)
- {
- /* Quick bounding box test to see if balls touch */
- if (ball[j].scrnx < x1 && ball[j].scrnx > x2 &&
- ball[j].scrny < y1 && ball[j].scrny > y2)
- {
- short dx = ball[j].x - ball[i].x;
- short dy = ball[j].y - ball[i].y;
-
- if (dx*dx + dy*dy < (BALLDIAMETER*BALLDIAMETER))
- {
- collision=TRUE;
-
- /* Bug-fix to stop multiple collisions for same balls */
- if (ball[j].lasthit==i && ball[i].lasthit==j)
- collision=FALSE;
-
- /* Balls are both stationary */
- else if (!ball[i].speed && !ball[j].speed)
- collision=FALSE;
-
- /* Balls must be unpotted */
- else if (ball[j].potted || ball[i].potted)
- collision=FALSE;
-
- if (collision) MakeCollision(i,j);
- }
- }
- }
- }
- }
-
- /**********************/
- void DrawBallDirect(col,x,y)
- short col,x,y;
- {
- SetAPen(rp,ballpalette[col]);
- rp->Mask = ballplanes[col];
- BltPattern(rp,ballmask,x,y,x+15,y+12,2);
-
- if (col==baize) return;
-
- if (col != white)
- {
- register char *ptr = bp2 + (y+3)*40 + ((x+7)>>3);
- register short data = 128 >> ((x+7) % 8);
-
- ptr[0] |= data; ptr[80] |= data;
- if (data==1) { ptr[40] |= 3; ptr[41] |= 128; }
- else if (data==128) { ptr[40] |= 192; ptr[39] |= 1; }
- else ptr[40] |= data + (data>>1) + (data<<1);
- }
- }
- /**********************/
- void DrawBall(i,status)
- short i,status;
- {
- short x = X1CORNER - 8 + ball[i].scrnx,
- y = Y2CORNER - 7 - ball[i].scrny;
-
- if (status==ON) DrawBallDirect(ball[i].colour,x,y);
- else if (status==OFF) DrawBallDirect(baize,x,y);
- else if (status==ICON)
- {
- DrawBallDirect(baize,287,11);
-
- switch(i)
- {
- case red:
- case yellow:
- case black:
- DrawBallDirect(i,287,11);
- break;
-
- case anyball:
- DrawBallDirect(red,287,11);
- ballmask = hybridmask; /* ballmask2 = hybridmask2; */
- DrawBallDirect(baize,287,11);
- DrawBallDirect(yellow,287,11);
- ballmask = &mask[12]; /* ballmask2 = mask2; */ break;
- }
- }
- }
- /**********************/
- void CheckResult()
- {
- short i,redpot=0,yellowpot=0,whitepot=0,blackpot=0,
- redsleft=FALSE,yellowsleft=FALSE;
-
- foul=FALSE;
-
- for (i=0; i<balls; i++)
- {
- if (ball[i].justpotted) switch (ball[i].colour)
- {
- case red: redpot++; break;
- case yellow: yellowpot++; break;
- case black: blackpot++; break;
- case white: whitepot++; break;
- }
-
- if (!ball[i].potted) switch (ball[i].colour)
- {
- case red: redsleft=TRUE; break;
- case yellow: yellowsleft=TRUE; break;
- }
- }
- switch(player[turn].colour)
- {
- case black:
- if (blackpot)
- {
- endofgame=TRUE;
- if (whitepot) foul=TRUE;
- }
- if (redpot || yellowpot) foul=TRUE;
- if (ball[firsthit].colour!=black) foul=TRUE;
- if (!blackpot) player[turn].goes=0;
- break;
-
- case red: /* Includes 9 ball variations... */
- if (!redsleft)
- {
- player[turn].colour=black;
- if (balls==10) player[1-turn].colour=black;
- }
- if (!yellowsleft && balls==16) player[1-turn].colour=black;
- if (!redpot) player[turn].goes--;
- if (blackpot)
- {
- endofgame=TRUE;
- if (!newbreak) foul=TRUE;
- break;
- }
- if (yellowpot) foul=TRUE;
- if (ball[firsthit].colour!=red) foul=TRUE;
- break;
- case yellow:
- if (!yellowsleft) player[turn].colour=black;
- if (!redsleft) player[1-turn].colour=black;
- if (!yellowpot) player[turn].goes--;
- if (blackpot) { foul=TRUE; endofgame=TRUE; }
- if (redpot) foul=TRUE;
- if (ball[firsthit].colour!=yellow) foul=TRUE;
- break;
- case anyball:
- if (blackpot)
- {
- endofgame=TRUE;
- if (!newbreak) foul=TRUE;
- break;
- }
- if (whitepot) foul=TRUE;
- else if (ball[firsthit].colour != red &&
- ball[firsthit].colour != yellow) foul=TRUE;
- else if (yellowpot && !redpot)
- { player[turn].colour=yellow; player[1-turn].colour=red; }
- else if (redpot && !yellowpot)
- { player[turn].colour=red; player[1-turn].colour=yellow; }
- else if (!redpot && !yellowpot) player[turn].goes--;
- break;
- }
- if (whitepot) foul=TRUE;
- if (endofgame) winner = (foul)? winner = 1-turn:turn;
-
- if (foul)
- {
- turn=1-turn; plyrbreak = 0;
- if (player[turn].colour==black) player[turn].goes = 1;
- else player[turn].goes = 2;
- for (i=0; i<3; i++)
- {
- WriteMessage(MSG_FOUL,40,5,NEW); Delay(20);
- ScrubMessage(); Delay(10);
- if (GetInput() == RETURN) break;
- }
- }
- else if (player[turn].goes==0)
- {
- if (plyrbreak > 2 && cheer) PlaySound(&audioinfo[CHEER],32);
- turn=1-turn; plyrbreak = 0; player[turn].goes = 1;
- }
- else if ((redpot>1 || yellowpot>1 ||
- (!ball[firsthit].potted && (redpot || yellowpot))) &&
- !newbreak)
- {
- plyrbreak++; WriteMessage(MSG_GOODSHOT,5,5,NEW);
- if (cheer) PlaySound(&audioinfo[CHEER],64); Delay(50);
- }
- else plyrbreak++;
-
- if (gametype!=PRACTICE) DrawBall(player[turn].colour,ICON);
- }
- /**********************/
- void DoOptions()
- {
- short i,j;
-
- gametype = arg[GAMETYPE];
- gamelength = arg[GAMELENGTH];
- stripper = arg[STRIPPER];
- opponent = arg[OPPONENT];
- balls = arg[BALLCOUNT];
-
- switch(gametype)
- {
- case PLYR1: CopyPlayer(2,0); CopyPlayer(opponent+4,1); break;
- case PLYR2: CopyPlayer(2,0); CopyPlayer(3,1); break;
- case PRACTICE: CopyPlayer(2,0); CopyPlayer(2,1); break;
- case DEMO:
- i = Rand(4); do j = Rand(4); while (i==j);
- CopyPlayer(4+i,0); CopyPlayer(4+j,1); break;
- }
- if (gamelength==BEST3) matches=3;
- else if (gamelength==BEST5) matches=5;
-
- rgb2[_ltbaize] = RGBbaize[arg[BAIZE]*5];
- rgb2[_dkbaize] = RGBbaize[arg[BAIZE]*5+1];
- rgb2[_baize] = RGBbaize[arg[BAIZE]*5+2];
- rgb2[_ltbaize2] = RGBbaize[arg[BAIZE]*5+3];
- rgb2[_ltbaize3] = RGBbaize[arg[BAIZE]*5+4];
-
- rgb2[_red] = RGBball[arg[BALL1]];
- rgb2[_highred] = 0xfff;
- rgb2[_yellow] = RGBball[arg[BALL2]];
- rgb2[_highyel] = 0xfff;
-
- FadeScreen(s,DOWN); SetRast(rp,_back);
- for (i=0; i<32; i++) rgb[i] = rgb2[i];
-
- if (gametype!=PRACTICE)
- {
- WriteMessage(player[0].nametag,80,80,NEW);
- WriteMessage(MSG_VS,0,80,FOLLOW);
- WriteMessage(player[1].nametag,0,80,FOLLOW);
- FadeScreen(s,UP); ClickDelay(150);
- }
- LoadIFF(&tableIFF,s,VIEW);
- BltBitMap(bm,182,107,&bufbm,200,0,71,79,0xc0,31,buffer);
- }
- /********************* Allocatation Routines ***********************/
- short AudioOpenIt()
- {
- short i;
-
- bufwave = AllocMem(BUFWAVELEN,MEMF_CLEAR | MEMF_CHIP);
-
- for (i=0; i<4; i++)
- {
- if (!(audio[i] = (struct IOAudio *) GetDeviceBlock(AUDIO_LEN)))
- return(0);
-
- audio[i]->ioa_Data = &Channel_Map[i];
- audio[i]->ioa_Length = 1; /* sizeof(Channel_Map); */
- audio[i]->ioa_Request.io_Message.mn_Node.ln_Pri = PRECIDENCE;
- if (OpenDevice("audio.device",NULL,audio[i],NULL)) return(0);
- /* Cut out initial noise */
- Audio_PerVol(audio[i],124,0);
- Audio_Write(audio[i],bufwave,BUFWAVELEN);
- }
- for (i=0; i<SAMPLES; i++)
- {
- while (!(fh = (struct FileHandle *)
- Open(audioinfo[i].filename,MODE_OLDFILE)));
-
- audioinfo[i].audio = audio[audioinfo[i].channel];
- audioinfo[i].wave =
- AllocMem(audioinfo[i].wavelen,MEMF_CLEAR | MEMF_CHIP);
- Seek((BPTR)fh,AM2,OFFSET_BEGINNING);
- MyRead(fh,audioinfo[i].wave,audioinfo[i].wavelen);
- Close((BPTR)fh);
- }
- return(1);
- }
- /************************/
- void CloseIt()
- {
- short i;
-
- prefs.KeyRptSpeed.tv_micro = oldkeyspeed;
- prefs.KeyRptDelay.tv_micro = oldkeydelay;
- SetPrefs(&prefs,sizeof(struct Preferences),TRUE);
-
- for (i=0; i<4; i++)
- FreeDeviceBlock(audio[i],(BYTE)CLOSE_DEVICE);
-
- for (i=0; i<SAMPLES; i++) if (audioinfo[i].wave)
- FreeMem(audioinfo[i].wave,audioinfo[i].wavelen);
- if (bufwave) FreeMem(bufwave,BUFWAVELEN);
-
- for (i=0; i<5; i++)
- if (bufbm.Planes[i]) FreeRaster(bufbm.Planes[i],320,256);
-
- if (memblock) FreeMem(memblock,MEMSIZE);
- if (w) CloseWindow(w);
- if (w2) CloseWindow(w2);
- if (s) CloseScreen(s);
- if (s2) CloseScreen(s2);
- if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
- if (GfxBase) CloseLibrary((struct Library *)GfxBase);
- }
- /**********************/
- UWORD Rand(max)
- UWORD max;
- {
- seed = seed*seed + 5*seed + VBeamPos();
- return (seed % max);
- }
- /**********************/
- void CheckAngle(angle)
- short *angle;
- {
- if (*angle > 359) *angle-=360;
- else if (*angle < 0) *angle+=360;
- }
- /**********************/
- short FindAngle(opp,adj,hyp)
- WORD opp,adj,hyp;
- {
- register short angle;
-
- if (opp > hyp) opp=hyp;
- else if (-opp > hyp) opp=-hyp;
- angle = quickarcsin[abs(opp * 5000 / hyp)];
- if (adj < 0 && opp >= 0) angle=180-angle;
- else if (adj < 0 && opp < 0) angle+=180;
- else if (adj >= 0 && opp < 0) angle=360-angle;
- return angle;
- }
- /**********************/
- WORD QuickRoot(x)
- long x;
- {
- register USHORT y=2,dy;
- register ULONG ysq;
-
- while(y*y < x) y<<=1;
- dy=y>>1;
-
- while(1)
- {
- ysq = y*y;
- if (ysq==x) return y;
- if (ysq < x) y+=dy;
- else y-=dy;
- if (!(dy>>=1))
- {
- if (y*y < x) y++; /* add 1? - hyp not < opp or adj! */
- return y;
- }
- }
- }
- /********************/
- APTR GetDeviceBlock(size)
- ULONG size;
- {
- struct MsgPort *port;
- APTR request;
-
- if (!(port = (struct MsgPort *) CreatePort(0,0))) return(NULL);
-
- if (!(request = (APTR) CreateExtIO(port,size)))
- { DeletePort(port); return(NULL); }
-
- return(request);
- }
- /********************/
- void FreeDeviceBlock(audio,close)
- struct IOAudio *audio;
- BYTE close;
- {
- if (audio->ioa_Request.io_Message.mn_ReplyPort)
- DeletePort(audio->ioa_Request.io_Message.mn_ReplyPort);
- if (close && audio->ioa_Request.io_Device) CloseDevice(audio);
- DeleteExtIO(audio);
- }
- /********************/
- void PlaySound(info,volume)
- struct audioinfostruct *info;
- short volume;
- {
- if (CheckIO(info->audio))
- {
- info->volume = volume;
- if (info->flag==RESET)
- {
- Audio_PerVol(info->audio,124,0);
- Audio_Write(info->audio,info->wave,info->wavelen);
- while(!(CheckIO(info->audio)));
- Audio_PerVol(info->audio,info->period,info->volume);
- Audio_Write(info->audio,bufwave,BUFWAVELEN);
- }
- else /* flag == BUFFER */
- {
- Audio_PerVol(info->audio,info->period,info->volume);
- if (info->bufstate = 1 - info->bufstate)
- Audio_Write(info->audio,info->wave,info->wavelen);
- else Audio_Write(info->audio,bufwave,BUFWAVELEN);
- }
- }
- }
- /********************/
- void Audio_PerVol(audio,period,volume)
- struct IOAudio *audio;
- UWORD period,volume;
- {
- audio->ioa_Request.io_Flags = ADIOF_SYNCCYCLE;
- audio->ioa_Period = period;
- audio->ioa_Volume = volume;
- audio->ioa_Request.io_Command = ADCMD_PERVOL;
- SendIO(audio);
- }
- /********************/
- void Audio_Write(audio,waveform,wavelength)
- struct IOAudio *audio;
- UBYTE *waveform;
- UWORD wavelength;
- {
- audio->ioa_Data = waveform;
- audio->ioa_Request.io_Command = CMD_WRITE;
- audio->ioa_Request.io_Flags = 0;
- audio->ioa_Length = wavelength;
- audio->ioa_Cycles = 1;
- SendIO(audio);
- }
-
- /************************/
- void CopyBalls(fromball,toball)
- struct ballstruct *fromball,*toball;
- {
- short i;
-
- for (i=0; i<balls; i++)
- {
- toball[i].x = fromball[i].x;
- toball[i].y = fromball[i].y;
- toball[i].scrnx = fromball[i].scrnx;
- toball[i].scrny = fromball[i].scrny;
- toball[i].angle = fromball[i].angle;
- toball[i].speed = fromball[i].speed;
- toball[i].potted = fromball[i].potted;
- toball[i].justpotted = fromball[i].justpotted;
- }
- }
-